#include "SGMExporter.h"

bool SGMExporter::ExportMaterial(IGameMaterial *material, std::ostream &os)
{
	if (material ->IsMultiType())
	{
		strcpy(resultMessage, "One of materials is multitype.\nYou cannot use different materials for various faces.");
		return false;
	}

	Point3 ambient;
	Point3 diffuse;
	Point3 specular;
	float specularLevel;
	float glossiness;
	float opacity;


	material ->GetAmbientData() ->GetPropertyValue(ambient);
	material ->GetDiffuseData() ->GetPropertyValue(diffuse);
	material ->GetSpecularData() ->GetPropertyValue(specular);
	material ->GetSpecularLevelData() ->GetPropertyValue(specularLevel);
	material ->GetGlossinessData() ->GetPropertyValue(glossiness);
	material ->GetOpacityData() ->GetPropertyValue(opacity);

	StreamWriter::WriteFloat(os, ambient.x);
	StreamWriter::WriteFloat(os, ambient.y);
	StreamWriter::WriteFloat(os, ambient.z);

	StreamWriter::WriteFloat(os, diffuse.x);
	StreamWriter::WriteFloat(os, diffuse.y);
	StreamWriter::WriteFloat(os, diffuse.z);

	StreamWriter::WriteFloat(os, specular.x);
	StreamWriter::WriteFloat(os, specular.y);
	StreamWriter::WriteFloat(os, specular.z);

	StreamWriter::WriteFloat(os, specularLevel);
	StreamWriter::WriteFloat(os, glossiness);
	StreamWriter::WriteFloat(os, opacity);

	bool hasTex = false;
	int texCount = material ->GetNumberOfTextureMaps();
	for (int i = 0; i < texCount; i++)
	{
		IGameTextureMap *tex = material ->GetIGameTextureMap(i);
		if (tex ->GetStdMapSlot() == ID_DI)
		{
			hasTex = true;
			StreamWriter::WriteByte(os, 1);
			ExportTexture(tex, os);
		}
	}

	if (!hasTex)
		StreamWriter::WriteByte(os, 0);

	StepProgress();

	return true;
}

bool SGMExporter::ExportTexture(IGameTextureMap *texture, std::ostream &os)
{
	char *texFileName = texture ->GetBitmapFileName();
	int texFileNameSize = strlen(texFileName);

	int nameOffset = texFileNameSize - 1;
	while ((texFileName[nameOffset] != '\\') && (nameOffset >= 0))
		nameOffset --;

	StreamWriter::WriteByte(os, texFileNameSize - nameOffset - 1);
	StreamWriter::WriteBuffer(os, texFileName + nameOffset + 1, texFileNameSize - nameOffset - 1);

	return true;
}

bool SGMExporter::ExportScene(std::ostream &os)
{
	IGameScene *igame_scene = GetIGameInterface();
	IGameConversionManager *cm = GetConversionManager();
	cm ->SetCoordSystem(IGameConversionManager::IGAME_OGL);

	igame_scene ->InitialiseIGame(false);
	igame_scene ->SetStaticFrame(0);

	int materialsCount = igame_scene ->GetRootMaterialCount();
	SetProgressSteps(materialsCount);
	StreamWriter::WriteInt(os, materialsCount);
	for (int i = 0; i < materialsCount; i++)
		if (!ExportMaterial(igame_scene ->GetRootMaterial(i), os))
			return false;

	igame_scene ->ReleaseIGame();

	return true;
}

bool SGMExporter::DoExport(const TCHAR *name, ExpInterface *ei, Interface *max_interface)
{
	bool result = true;

	std::ofstream file(name, std::ios::binary);
	ExportScene(file);
	file.close();

	if (result)
		strcpy(resultMessage, "Materials has been exported successfull");
	//else
		//TODO: kasowanie pliku!!

	return result;
}

void SGMExporter::RegisterObserver(IProgressObserver *observer)
{
	observers.push_back(observer);
}

void SGMExporter::UnregisterObserver(IProgressObserver *observer)
{
	//TODO:
}

void SGMExporter::SetProgressSteps(int progressSteps)
{
	std::vector<IProgressObserver*>::iterator i;
	for (i = observers.begin(); i != observers.end(); i++)
		(*i) ->SetProgressSteps(this, progressSteps);
}

void SGMExporter::StepProgress()
{
	std::vector<IProgressObserver*>::iterator i;
	for (i = observers.begin(); i != observers.end(); i++)
		(*i) ->StepProgress(this);
}

const char *SGMExporter::GetResultMessage()
{
	return "";
}